home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / share / pyshared / AptUrl / Parser.py < prev    next >
Text File  |  2009-09-18  |  5KB  |  144 lines

  1. # Copyright (c) 2007-2008 Canonical
  2. #
  3. # AUTHOR:
  4. # Michael Vogt <mvo@ubuntu.com>
  5. # With contributions by Siegfried-A. Gevatter <rainct@ubuntu.com>
  6. #
  7. # This file is part of AptUrl
  8. #
  9. # AptUrl is free software; you can redistribute it and/or
  10. # modify it under the terms of the GNU General Public License as published
  11. # by the Free Software Foundation; either version 2 of the License, or (at
  12. # your option) any later version.
  13. #
  14. # AptUrl is distributed in the hope that it will be useful,
  15. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17. # General Public License for more details.
  18. #
  19. # You should have received a copy of the GNU General Public License
  20. # along with GDebi; if not, write to the Free Software
  21. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  22.  
  23. import os
  24. import string
  25. from string import Template
  26. from subprocess import Popen, PIPE
  27. from Helpers import get_dist
  28. from Helpers import utf8, _, _n
  29.  
  30. class InvalidUrlException(Exception):
  31.     pass
  32.  
  33. # substituion mapping
  34. apturl_substitution_mapping = {
  35.     "distro" : get_dist(),
  36.     "kernel" : os.uname()[2] 
  37. }
  38.  
  39. # whitelist for the uri
  40. whitelist = []
  41. whitelist.extend(string.ascii_letters)
  42. whitelist.extend(string.digits)
  43. whitelist.extend(['_',':','?','/','+','.','~','=','<','>','-',',','$','&'])
  44.  
  45.  
  46. class AptUrl(object):
  47.     " a class that contains the parsed data from an apt url "
  48.     def __init__(self):
  49.         self.package = None
  50.         self.schema = None
  51.         self.minver = None
  52.         self.refresh = None
  53.         # for added repos
  54.         self.keyfile = None
  55.         self.repo_url = None
  56.         self.dist = '/'     
  57.         # for known sections 
  58.         self.section = []
  59.         # for known channels
  60.         self.channel = None
  61.  
  62. def is_format_package_name(string):
  63.     " return True if string would be an acceptable name for a Debian package "
  64.     
  65.     return (string.replace("+", "").replace("-", "").replace(".", "").isalnum() 
  66.         and string.islower() and string[0].isalnum() and len(string) > 1)
  67.  
  68. def do_apt_url_substitution(apt_url, mapping):
  69.     " substitute known templates against the field package and channel "
  70.     for field in ["package","channel"]:
  71.         if getattr(apt_url, field):
  72.             s=Template(getattr(apt_url, field))
  73.             setattr(apt_url, field, s.substitute(mapping))
  74.  
  75. def match_against_whitelist(raw_url):
  76.     " test if the url matches the internal whitelist "
  77.     for char in raw_url:
  78.         if not char in whitelist:
  79.             raise InvalidUrlException, _("Non whitelist char in the uri")
  80.     return True
  81.  
  82. def set_value(apt_url, s):
  83.     " set a key,value pair from string s to AptUrl object "
  84.     (key, value) = s.split("=")
  85.     try:
  86.         if ' ' in value:
  87.             raise InvalidUrlException, _("Whitespace in key=value")
  88.         if type(getattr(apt_url, key)) == type([]):
  89.             getattr(apt_url, key).append(value)
  90.         else:
  91.             setattr(apt_url, key, value)
  92.     except Exception, e:
  93.         raise InvalidUrlException, _("Exception '%s'") % e
  94.  
  95.  
  96. def parse(full_url, mapping=apturl_substitution_mapping):
  97.     " parse an apt url and return a list of AptUrl objects "
  98.     # apt:pkg1?k11=v11?k12=v12,pkg2?k21=v21?k22=v22,...
  99.     res = []
  100.     
  101.     # check against whitelist
  102.     match_against_whitelist(full_url)
  103.     for url in full_url.split(";"):
  104.         if not ":" in url:
  105.             raise InvalidUrlException, _("No ':' in the uri")
  106.  
  107.         # now parse it
  108.  
  109.         (schema, packages) = url.split(":", 1)
  110.         packages = packages.split(",")
  111.  
  112.         for package in packages:
  113.             apt_url = AptUrl()
  114.             apt_url.schema = schema
  115.             # check for schemas of the form: apt+http://
  116.             if schema.startswith("apt+"):
  117.                 apt_url.repo_url = schema[len("apt+"):] + ":" + package.split("?",1)[0]
  118.             else:
  119.                 if "?" in package:
  120.                     apt_url.package = package.split("?")[0].lstrip("/")
  121.                 else:
  122.                     apt_url.package = package.lstrip("/")
  123.  
  124.             # now parse the ?... bits
  125.             if "?" in package:
  126.                 key_value_pairs = package.split("?")[1:]
  127.                 for s in key_value_pairs:
  128.                     if "&" in s:
  129.                         and_key_value_pairs = s.split("&")
  130.                         for s in and_key_value_pairs:
  131.                             set_value(apt_url, s)
  132.                     else:
  133.                         set_value(apt_url, s)
  134.  
  135.             # do substitution (if needed) 
  136.             do_apt_url_substitution(apt_url, mapping)
  137.             
  138.             # check if the package name is valid
  139.             if not is_format_package_name(apt_url.package):
  140.                 raise InvalidUrlException, "Invalid package name '%s'" % apt_url.package
  141.             
  142.             res.append(apt_url)
  143.     return res    
  144.